package com.yonyou.pmclouds.basecom.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.yonyou.pmclouds.basecom.conf.NCInvokerConfiguration;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.plan.plandriven.entity.NcDepartmentVO;
import com.yonyou.pmclouds.plan.plandriven.entity.NcDeptQueryParamVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 查询NC部门
 *
 * @author th
 * @date 2019/11/26 10:29
 */
@Slf4j
@Component
public class NCDepartmentQueryService {
    public static final String QUERY_DEPARTMENT_SERVICE_NAME = "DeptQueryServlet";
    /**
     * nc直连调用接口
     */
    public static final String NCC_SERVICE_SERVLET_PATH = "/service/DeptQueryServlet";
    /**
     * 友企联调用接口
     */
    public static final String NC_UBL_SERVICE = "nc.bs.pmcloud.servlet.ublimpl.DeptQueryImp4UBL";

    @Autowired
    private NCInvokerConfiguration.Invoker invoker;

    private ObjectMapper mapper = new ObjectMapper();

    public List<NcDepartmentVO> queryDepartmentFromNc(NcDeptQueryParamVO paramVO) throws BusinessException {
        List<NcDepartmentVO> result = new ArrayList<>();

        if (paramVO == null || (StringUtils.isEmpty(paramVO.getPkOrg()) && CollectionUtils.isEmpty(paramVO.getPkDepts())))
            return result;

        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("pkDepts", paramVO.getPkDepts());
        requestParams.put("pkOrg", paramVO.getPkOrg());

        // 返回结果
        NCInvokerConfiguration.Result invokeResult = null;
        Map resultMap;

        try {
            // 调用NCC发送待办消息接口
            Future<NCInvokerConfiguration.Result> resultFuture = invoker.invokeAsync(QUERY_DEPARTMENT_SERVICE_NAME,
                    NCC_SERVICE_SERVLET_PATH, requestParams, RuntimeEnvironment.getTenantId(),
                    RuntimeEnvironment.getLoginUserId(), null);

            // 阻塞，设置超时时间5秒
            invokeResult = resultFuture.get(5, TimeUnit.SECONDS);
            if (invokeResult == null || invokeResult.getResult() == null) {
                log.error("查询部门失败, 返回结果: {}", invokeResult == null ? null : invokeResult.getResult());
                return new ArrayList<>();
            }

            if (!NCInvokerConfiguration.Result.STATUS_OK.equals(invokeResult.getStatus())) {
                log.error("查询部门失败, 返回状态: {}, 返回结果: {}", invokeResult.getStatus(), invokeResult.getResult());
                return new ArrayList<>();
            }

            resultMap = mapper.readValue(invokeResult.getResult(), Map.class);
            if (!"ok".equals(resultMap.get("resultCode"))) {
                log.error("查询部门失败，返回result：{}", invokeResult.getResult());
                return new ArrayList<>();
            }
            CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, NcDepartmentVO.class);
            result = mapper.readValue(JSON.toJSONString(resultMap.get("result")), listType);
        } catch (IOException e) {
            log.error("unserialization failed, result is {}", invokeResult.getResult());
            log.error("计划待办消息发送结果反序列失败", e);
            return new ArrayList<>();
        } catch (Exception e) {
            log.error("查询部门失败, 返回结果: {}", invokeResult == null ? null : invokeResult.getResult());
            log.error("查询部门失败", e);
            return new ArrayList<>();
        }

        return result;
    }
}
